#!/usr/bin/env lua

-- Lua Battle System - 自动化测试脚本
-- 使用方法: lua scripts/run_tests.lua [test_type] [options]

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;src/characters/?.lua;src/skills/?.lua;src/items/?.lua;src/ai/?.lua;src/battle/?.lua;res/data/?.lua;tests/?.lua;tests/unit/?.lua;tests/integration/?.lua;tests/performance/?.lua'

local TestFramework = require("src.utils.test_framework")
local TestHelpers = require("tests.test_helpers")

-- 测试配置
local TestConfig = {
    -- 测试类型
    UNIT_TESTS = "unit",
    INTEGRATION_TESTS = "integration",
    PERFORMANCE_TESTS = "performance",
    ALL_TESTS = "all",

    -- 测试文件映射
    test_files = {
        unit = {
            "tests/unit/utils/test_logger.lua",
            "tests/unit/utils/test_config_loader.lua",
            "tests/unit/characters/test_character_basic.lua"
            -- 可以添加更多单元测试文件
        },
        integration = {
            "tests/integration/test_skills_integration.lua",
            "tests/integration/test_battle_integration.lua"
            -- 可以添加更多集成测试文件
        },
        performance = {
            "tests/performance/test_ai_performance.lua",
            "tests/performance/test_system_performance.lua"
            -- 可以添加更多性能测试文件
        }
    },

    -- 命令行选项
    options = {
        verbose = false,
        continue_on_error = false,
        generate_report = true,
        report_file = "test_report.txt"
    }
}

-- 帮助信息
local function print_help()
    print([[
Lua Battle System 测试运行器

使用方法:
    lua scripts/run_tests.lua [test_type] [options]

测试类型:
    unit                    运行单元测试
    integration             运行集成测试
    performance             运行性能测试
    all                     运行所有测试

选项:
    -v, --verbose           详细输出
    -c, --continue          遇到错误时继续执行
    -r, --report <file>     生成测试报告到指定文件
    -h, --help              显示此帮助信息

示例:
    lua scripts/run_tests.lua unit
    lua scripts/run_tests.lua all -v -c
    lua scripts/run_tests.lua integration --report report.txt
]])
end

-- 解析命令行参数
local function parse_arguments(args)
    local test_type = TestConfig.ALL_TESTS
    local options = {}

    -- 解析测试类型
    if #args >= 1 then
        local arg = args[1]
        if arg ~= "-v" and arg ~= "--verbose" and arg ~= "-c" and arg ~= "--continue" and
           arg ~= "-h" and arg ~= "--help" and arg ~= "-r" and arg ~= "--report" then
            if arg == TestConfig.UNIT_TESTS or arg == TestConfig.INTEGRATION_TESTS or
               arg == TestConfig.PERFORMANCE_TESTS or arg == TestConfig.ALL_TESTS then
                test_type = arg
            else
                print("错误: 未知的测试类型 '" .. arg .. "'")
                print_help()
                return nil
            end
        end
    end

    -- 解析选项
    local i = (args[1] ~= "-v" and args[1] ~= "--verbose" and args[1] ~= "-c" and args[1] ~= "--continue" and
                args[1] ~= "-h" and args[1] ~= "--help" and args[1] ~= "-r" and args[1] ~= "--report") and 1 or 0

    while i <= #args do
        local arg = args[i]

        if arg == "-v" or arg == "--verbose" then
            options.verbose = true
        elseif arg == "-c" or arg == "--continue" then
            options.continue_on_error = true
        elseif arg == "-r" or arg == "--report" then
            i = i + 1
            if i <= #args then
                options.report_file = args[i]
            else
                print("错误: --report 选项需要指定文件名")
                return nil
            end
        elseif arg == "-h" or arg == "--help" then
            print_help()
            return nil
        else
            print("错误: 未知的选项 '" .. arg .. "'")
            print_help()
            return nil
        end

        i = i + 1
    end

    return {
        test_type = test_type,
        options = options
    }
end

-- 运行指定类型的测试
local function run_tests_by_type(test_type, options)
    local test_files = {}

    if test_type == TestConfig.ALL_TESTS then
        -- 合并所有测试文件
        for _, files in pairs(TestConfig.test_files) do
            for _, file in ipairs(files) do
                table.insert(test_files, file)
            end
        end
    else
        test_files = TestConfig.test_files[test_type] or {}
    end

    if #test_files == 0 then
        print("警告: 没有找到 " .. test_type .. " 类型的测试文件")
        return true, 0, 0, 0
    end

    print(string.format("开始运行 %d 个 %s 测试...\n", #test_files, test_type))

    -- 设置测试环境
    TestHelpers.Environment.setup()

    local total_suites = 0
    local passed_suites = 0
    local failed_suites = 0
    local total_errors = 0

    -- 运行每个测试文件
    for _, test_file in ipairs(test_files) do
        if options.verbose then
            print("加载测试文件: " .. test_file)
        end

        total_suites = total_suites + 1

        local success, test_module = pcall(dofile, test_file)
        if not success then
            print("❌ 加载测试文件失败: " .. test_file)
            print("错误: " .. tostring(test_module))
            failed_suites = failed_suites + 1
            total_errors = total_errors + 1

            if not options.continue_on_error then
                break
            else
                goto continue
            end
        end

        if type(test_module) ~= "table" or not test_module.run_tests then
            print("❌ 测试文件格式错误: " .. test_file)
            failed_suites = failed_suites + 1
            total_errors = total_errors + 1

            if not options.continue_on_error then
                break
            else
                goto continue
            end
        end

        -- 运行测试套件
        local success = test_module.run_tests()

        if success then
            passed_suites = passed_suites + 1
            if options.verbose then
                print("✅ 测试通过: " .. test_file)
            end
        else
            failed_suites = failed_suites + 1
            print("❌ 测试失败: " .. test_file)

            if not options.continue_on_error then
                break
            end
        end

        ::continue::
    end

    -- 清理测试环境
    TestHelpers.Environment.cleanup()

    return true, passed_suites, failed_suites, total_errors
end

-- 生成测试报告
local function generate_report(passed, failed, errors, options)
    local report_content = string.format([[
Lua Battle System 测试报告
========================
生成时间: %s

测试结果:
- 通过: %d
- 失败: %d
- 错误: %d
- 总计: %d
- 成功率: %.2f%%

详细统计:
]], os.date("%Y-%m-%d %H:%M:%S"), passed, failed, errors, passed + failed,
        (passed + failed) > 0 and (passed / (passed + failed) * 100) or 0)

    -- 添加详细测试统计
    local stats = TestFramework.get_stats()
    report_content = report_content .. string.format([[
- 总测试数: %d
- 通过测试: %d
- 失败测试: %d
- 错误测试: %d
- 测试成功率: %.2f%%
]], stats.total, stats.passed, stats.failed, stats.errors, stats.success_rate)

    -- 写入报告文件
    local report_file = options.report_file or TestConfig.options.report_file
    local file = io.open(report_file, "w")
    if file then
        file:write(report_content)
        file:close()
        print("测试报告已生成: " .. report_file)
    else
        print("警告: 无法创建测试报告文件: " .. report_file)
    end
end

-- 主函数
local function main()
    print("Lua Battle System 测试运行器")
    print("=" .. string.rep("=", 49))

    -- 解析命令行参数
    local parsed = parse_arguments(arg)
    if not parsed then
        return 1
    end

    local test_type = parsed.test_type
    local options = parsed.options

    -- 合并默认选项
    for key, value in pairs(TestConfig.options) do
        if options[key] == nil then
            options[key] = value
        end
    end

    -- 显示配置信息
    if options.verbose then
        print("测试类型: " .. test_type)
        print("详细输出: " .. tostring(options.verbose))
        print("遇到错误继续: " .. tostring(options.continue_on_error))
        print("生成报告: " .. tostring(options.generate_report))
        if options.report_file then
            print("报告文件: " .. options.report_file)
        end
        print()
    end

    -- 运行测试
    local success, passed, failed, errors = run_tests_by_type(test_type, options)

    if not success then
        print("测试运行失败")
        return 1
    end

    -- 显示测试结果
    print("\n" .. string.rep("=", 50))
    print("测试结果汇总")
    print(string.rep("=", 50))
    print(string.format("总测试套件: %d", passed + failed))
    print(string.format("通过: %d ✅", passed))
    print(string.format("失败: %d ❌", failed))
    print(string.format("错误: %d 💥", errors))

    local total = passed + failed
    local success_rate = total > 0 and (passed / total * 100) or 0
    print(string.format("成功率: %.2f%%", success_rate))

    if failed == 0 and errors == 0 then
        print("🎉 所有测试都通过了！")
        local result = 0
    else
        print("⚠️  有测试失败或出现错误")
        local result = 1
    end

    -- 生成测试报告
    if options.generate_report then
        generate_report(passed, failed, errors, options)
    end

    print(string.rep("=", 50))

    return failed > 0 or errors > 0 and 1 or 0
end

-- 运行主函数
local exit_code = main()
os.exit(exit_code)